package com.xl.studentpass.component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xl.studentpass.entity.TaskInfoEntity;
import com.xl.studentpass.entity.UserEntity;
import com.xl.studentpass.mapper.PublishTaskMapper;
import com.xl.studentpass.mapper.UserMapper;
import com.xl.studentpass.utils.LocalDateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.math.BigDecimal;
import java.util.HashMap;

import static com.xl.studentpass.utils.TaskOrderStatus.*;

/**
 * @author xxl
 */
@Component
@Slf4j
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    @Resource
    PublishTaskMapper publishTaskMapper;
    @Value("${redis.order.key}")
    private String orderKey;
    @Value("${redis.task.key}")
    private String taskKey;
    @Resource
    WebSocket webSocket;
    @Resource
    UserMapper userMapper;


    public RedisKeyExpirationListener(RedisMessageListenerContainer container) {
        super(container);
    }

    /**
     * 针对redis数据失效事件，进行数据处理
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        System.out.println("===============" + message.toString());
        //生效的key
        String key = message.toString();
        //从失效key中筛选代表订单失效的key
        if (key != null && key.startsWith(orderKey)) {
            listeningOrder(key);
        }
        if (key != null && key.startsWith(taskKey)) {
            listeningTask(key);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    protected void listeningTask(String key) {
        String taskNo = key.substring(4);
        JSONObject jsonObject = JSON.parseObject(key.split("%")[1]);
        Integer taskId = jsonObject.getInteger("taskId");
        //接受者
        Integer accepter = jsonObject.getInteger("accepter");
        //发布者
        Integer publisher = jsonObject.getInteger("publisher");

        //通知任务发布者
        HashMap<String, Object> messages = new HashMap<>();

        messages.put("orderId", taskId);
        messages.put("taskName", jsonObject.get("taskName"));
        messages.put("createTime", "");
        messages.put("orderUserId", accepter);
        messages.put("operate", "system");

        webSocket.sendOneMessage(String.valueOf(publisher), JSON.toJSONString(messages));

        TaskInfoEntity taskInfo = publishTaskMapper.selectById(taskId);
        BigDecimal taskPrice = taskInfo.getTaskPrice();
        UserEntity user = userMapper.selectById(accepter);
        BigDecimal balance = user.getBalance();
        user.setBalance(balance.add(taskPrice));
        userMapper.updateById(user);
    }

    private void listeningOrder(String key) {

        //截取订单号，查询订单，如果是未支付状态则取消订单
        String orderNo = key.substring(5);

        TaskInfoEntity taskInfo = publishTaskMapper.selectById(orderNo);
        Integer statusId = taskInfo.getStatusId();
        if (ORDER_RECEIVED.getId().equals(statusId) || ORDER_COMPLETION.getId().equals(statusId)) {
            return;
        }

        taskInfo.setStatusId(ORDER_FAILURE.getId());
        String operaTime = LocalDateUtils.getLocalDateTimeStr();
        taskInfo.setOperaTime(operaTime);

        publishTaskMapper.updateById(taskInfo);
        log.info("订单号为：" + orderNo + "的订单超时未支付，取消订单");

    }
}